package Fundamental.memory.stringTest;


import java.util.HashSet;
import java.util.Iterator;

public class StringTest {
    public static void main(String[] args) {
        String s1 = "1";
        String s2 = "1";
        // s1 和 s2 都指向了常量池中的地址。所以他们的值是一样的
        System.out.println(s1 == s2);

        //--------------------------
        String s3 = "22";
        String s4 = "2"+"2";
        // s3 s4 两个都指向了常量池中的地址，所以是一样的
        System.out.println(s3 == s4);

        String s5 = "33";
        String s6 = new String("33");
        // s5 指向的是常量池中的地址，s6 指向的是堆里面的地址，所以两个不同。
        System.out.println(s5 == s6);

        String s7 = "44";
        String s8 = "4" + new String("4");
        // s7 指向的是常量池中的地址，s8 由于常量和 new 出来的字符串拼接，所以也指向的是堆内存地址
        System.out.println(s7 == s8);

        String s9 = new String("55");
        String s10 = new String("55");
        System.out.println(s9 == s10);

        String s11 = "ab";
        String s12 = "cd";
        String s13 = s11 + s12 ;
        // s11 + s12 编译器会自动的使用 StringBuilder 来优化，使用 toString 方法来返回字符串
        // s11 + s12 是在运行时，才知道返回的什么内容。
        System.out.println(s13 == "abcd");

        String s14 = "ab";
        String s15 = "cd";
        String s16 = "ab" + s15 ;
        // "ab" + s15 也是在运行时才知道它是什么东西的，所以 s16 是指向堆内存地址的。
        System.out.println(s16 == "abcd");

        String s17 = "ab";
        final String s18 = "cd";
        String s19 = "ab" + s18 ;
        // s18 使用了 final 做了修饰了，所以在编译的时候 s18 的值就能确定了。所以 s19 指向的是字符串常量池中的地址
        System.out.println(s19 == "abcd");

        String s20 = "a2";
        String s21 = "a" + 2 ;
        // "a" 和 2 都是字面量，所以在编译期间就能确定 s21 的值，所以 s21 是可以在常量池中找到 a2 的。
        System.out.println(s20 == s21);

        String s22 = "a2.3";
        String s23 = "a"+2.3;
        // 和上面的原理是一样的。
        System.out.println(s22 == s23);
        StringTest o1 = new StringTest();
        o1.test01();


        String s24 = new String("1") + new String("23");
        s24.intern();
        String s25 = "123";
        System.out.println(s24 == s25);

        String s26 = new String("1") + new String("23");
        String s27 = "123";
        s26.intern();
        System.out.println(s27 == s26);

        String s28 = "a";
        int i = 0 ;
        String s29 = s28 + i ;
        System.out.println(s28 == s29);

        HashSet<String> hs = new HashSet<>();
        hs.add("a");
        hs.add("b");
        hs.add("c");
        hs.add("d");
        for (String h : hs) {
            h = "a";
            System.out.println(h);
        }
        hs.forEach(x -> System.out.println(x));
        HashSet<Integer> ints = new HashSet<>();
        ints.add(1);
        ints.add(2);
        Iterator<Integer> iterator = ints.iterator();
        Integer next ;
        while(iterator.hasNext()){
            next = iterator.next();
            next = 1 ;
        }
        for (Integer anInt : ints) {
            anInt = 1 ;
        }
        ints.forEach(x -> System.out.println(x));

    }
    public void test01(){
        String s24 = "aa";
        final String s25 = get();
        System.out.println(s24 == s25);
    }
    public static String get(){
        return "aa";
    }
}
